package com.model.project;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.TableGenerator;

import com.core.protocols.IKVObject;
import com.core.utils.LocalizableString;
import com.model.KeyValue;
import com.model.user.User;

@Entity
public class ProjectItem
        implements IKVObject {

	private int               id;
	private String            name;
	private String            description;
	private String            owner;
	private Date              createDate;
	private Date              releaseDate;
	private User              assignee;
	private User              reporter;
	private Set <Version>     projectVersions = new HashSet <Version>();
	private Set <ProjectTask> projectTasks    = new HashSet <ProjectTask>();
	private Set <TeamMember>  projectTeam     = new HashSet <TeamMember>();



	@Override
	public void assignTo ( IKVObject object ) {

		if ( object == null ) {
			return;
		}

		ProjectItem objectToUpdate = (ProjectItem) object;
		objectToUpdate.name = this.name;
		objectToUpdate.description = this.description;
		objectToUpdate.createDate = this.createDate;
		objectToUpdate.assignee = this.assignee;
		objectToUpdate.reporter = this.reporter;

	}



	@Id
	@TableGenerator(allocationSize = 10, table = "Generators", pkColumnName = "generatorName", pkColumnValue = "generatorProjectItem", name = "generatorProjectItem")
	@GeneratedValue(strategy = GenerationType.TABLE, generator = "generatorProjectItem")
	public Integer getId () {

		return id;
	}



	public ProjectItem() {

	}



	public void setId ( int id ) {

		this.id = id;
	}



	@Column(nullable = false, unique = true)
	public String getName () {

		return name;
	}



	public void setName ( String name ) {

		this.name = name;
	}



	@Lob
	public String getDescription () {

		return description;
	}



	public void setDescription ( String description ) {

		this.description = description;
	}



	public Date getReleaseDate () {

		return releaseDate;
	}



	public void setReleaseDate ( Date releaseDate ) {

		this.releaseDate = releaseDate;
	}



	public Date getCreateDate () {

		return createDate;
	}



	public void setCreateDate ( Date createDate ) {

		this.createDate = createDate;
	}



	public String getOwner () {

		return owner;
	}



	public void setOwner ( String owner ) {

		this.owner = owner;
	}



	@ManyToMany
	@JoinTable(name = "projectitem_team", joinColumns = {
		@JoinColumn(name = "PROJECT_ID")
	}, inverseJoinColumns = {
		@JoinColumn(name = "MEMBER_ID")
	})
	public Set <TeamMember> getProjectTeam () {

		return projectTeam;
	}



	public void setProjectTeam ( Set <TeamMember> projectTeam ) {

		this.projectTeam = projectTeam;
	}



	@OneToMany(cascade = CascadeType.ALL)
	@JoinTable(name = "projectitem_tasks", joinColumns = {
		@JoinColumn(name = "PROJECT_ID")
	}, inverseJoinColumns = {
		@JoinColumn(name = "TASK_ID")
	})
	public Set <ProjectTask> getProjectTasks () {

		return this.projectTasks;
	}



	public void setProjectTasks ( Set <ProjectTask> tasks ) {

		this.projectTasks = tasks;
	}



	@OneToMany(cascade = CascadeType.ALL)
	@JoinTable(name = "projectitem_version", joinColumns = {
		@JoinColumn(name = "PROJECT_ID")
	}, inverseJoinColumns = {
		@JoinColumn(name = "Version_ID")
	})
	public Set <Version> getProjectVersions () {

		return this.projectVersions;
	}



	public void setProjectVersions ( Set <Version> versions ) {

		this.projectVersions = versions;
	}



	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@JoinColumn(nullable = true, updatable = true)
	public User getAssignee () {

		return assignee;
	}



	public void setAssignee ( User assignee ) {

		this.assignee = assignee;
	}



	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@JoinColumn(nullable = true, updatable = true)
	public User getReporter () {

		return reporter;
	}



	public void setReporter ( User reporter ) {

		this.reporter = reporter;
	}



	@Override
	public KeyValue idValue () {

		String strIdValue = this.getId().toString();
		return new KeyValue(this.fieldNameAsId(), strIdValue, false);

	}



	@Override
	public String fieldNameAsId () {

		return "id";
	}



	@Override
	public KeyValue nameValue () {

		String strIdValue = this.getName().toString();
		return new KeyValue(this.fieldNameAsName(), strIdValue, false);

	}



	@Override
	public String fieldNameAsName () {

		return "name";
	}



	public String localizableDescription () {

		return LocalizableString.sharedInstance().localizable("entity.ProjectItem.description");
	}
}
